iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
0
Software Development

學習Go系列 第 16

Go day 16 (goroutines)

  • 分享至 

  • xImage
  •  

goroutines

goroutines 是類似 thread 的東西,但它比 thread 還輕量.它被視為一個獨立的工作單位.

一般呼叫 main function 裡面的程式會造順序執行.

package main

import (
	"fmt"
)

func main() {
	showMessage("start")
	showMessage("1")
	showMessage("2")
	showMessage("3")
	showMessage("4")
	showMessage("end")
	fmt.Println("done")
}

func showMessage(msg string) {
	fmt.Println(msg)
}

印出

start
1
2
3
4
end
done

建立一個 goroutine 就是在使用 function 面前再加上 go 關鍵字.
下面的例子 main function 不會等 goroutine 回傳結果,還沒等 goroutine 印出數字時,程式就會結束了.
所以加上 fmt.Scanln(&input) 讓程式暫停,等隨便按了一個鍵後再按 Enter main function 才會結束.
每次數字印出的順序都會不一樣就看哪個 goroutine 先執行完,所以這些 goroutine 是同時在進行工作的.

package main

import (
	"fmt"
)

func main() {
	showMessage("start")
	go showMessage("1")
	go showMessage("2")
	go showMessage("3")
	go showMessage("4")
	showMessage("end")
	var input string
	fmt.Scanln(&input)
	fmt.Println("done")
}

func showMessage(msg string) {
	fmt.Println(msg)
}

印出

start
end
2
4
3
1
(Enter)
done

由於 goroutine 會同時執行,所以有用到共用的資源時,執行順序有可能會影響到最後的結果

package main

import "fmt"

func main() {
	sum := 10
	go func() { sum += 3 }()
	go func() { sum -= 5 }()
	go func() { sum *= 2 }()
	var input string
	fmt.Scanln(&input)
	fmt.Println(sum)
}

像上面的範例排列組合有幾種,每次執行有可能出現不同答案

(10 + 3 - 5) * 2 = 16
10 * 2 + 3 - 5 = 18
(10 + 3) * 2 - 5 = 21
...

在 The Go Programming Language 這本書有寫這個範例,執行的時候會先看到 spinner function 一直轉圈圈,
直到算出 fibonacci 數之後才會停止印出結果.代表說這兩件事是同時在做的也就是 concurrency 的概念.

package main

import (
	"fmt"
	"time"
)

func main() {
	go spinner(100 * time.Millisecond)
	const n = 45
	fibN := fib(n)
	fmt.Printf("\rFibonacci(%d) = %d \n", n, fibN)
}
func spinner(delay time.Duration) {
	for {
		for _, r := range `-\|/` {
			fmt.Printf("\r%c", r)
			time.Sleep(delay)
		}
	}
}
func fib(x int) int {
	if x < 2 {
		return x
	}
	return fib(x-1) + fib(x-2)
}


上一篇
Go day 15 (flow control)
下一篇
Go day 17 (channel)
系列文
學習Go30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言